/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.xtd.view.employment;

import com.xtd.facade.SystemException;
import com.xtd.facade.admin.XtdgroupFacade;
import com.xtd.facade.admin.XtduserFacade;
import com.xtd.facade.employment.DepartmentPostFacade;
import com.xtd.facade.employment.EmployeeFacade;
import com.xtd.facade.employment.PayrollFacade;
import com.xtd.model.admin.UserGroup;
import com.xtd.model.admin.Xtdgroup;
import com.xtd.model.admin.Xtduser;
import com.xtd.model.employment.DepartmentPost;
import com.xtd.model.employment.Employee;
import com.xtd.model.employment.Payroll;
import com.xtd.view.AbstractManager;
import com.xtd.view.ApplicationBean;
import com.xtd.view.SessionBean;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.model.SelectItem;
import javax.faces.validator.ValidatorException;
import org.primefaces.context.RequestContext;
import org.primefaces.event.CloseEvent;
import org.primefaces.model.DualListModel;

/**
 *
 * @author Lu Yuanbin
 */
@ManagedBean
@SessionScoped
public class EmployeeManager extends AbstractManager {

    @EJB
    EmployeeFacade employeeFacade;
    @EJB
    DepartmentPostFacade departmentPostFacade;
    @EJB
    PayrollFacade payrollFacade;
    @EJB
    XtduserFacade xtduserFacade;
    @EJB
    XtdgroupFacade xtdgroupFacade;
    private List<Employee> employeeList;
    private Employee selectedEmployee;
    private String searchContent;
    private String selectedDepartment;
    private String selectedPost;
    private List<SelectItem> postSelectItems;
    private List<SelectItem> departmentPostSelectItems;
    private int selectedDepartmentPostId;
    private int selectedEmployeeId;
    private List<SelectItem> employeeSelectItems;
    private DualListModel<Xtdgroup> xtdGroups;
    @ManagedProperty(value = "#{applicationBean}")
    private ApplicationBean applicationBean;
    @ManagedProperty(value = "#{sessionBean}")
    private SessionBean sessionBean;
    private List<Payroll> payrollList;
    private Employee[] selecteEmployeeList;
    private Date startDate;
    private Date endDate;

    /** Creates a new instance of EmployeeManager */
    public EmployeeManager() {
    }

    /**
     * @return the employeeList
     */
    public List<Employee> getEmployeeList() {
        if (employeeList == null) {
            employeeList = new ArrayList();
        }
        return employeeList;
    }

    /**
     * @param employeeList the employeeList to set
     */
    public void setEmployeeList(List<Employee> employeeList) {
        this.employeeList = employeeList;
    }

    /**
     * @return the selectedEmployee
     */
    public Employee getSelectedEmployee() {
        return selectedEmployee;
    }

    /**
     * @param selectedEmployee the selectedEmployee to set
     */
    public void setSelectedEmployee(Employee selectedEmployee) {
        this.selectedEmployee = selectedEmployee;
    }

    /**
     * @return the searchContent
     */
    public String getSearchContent() {
        return searchContent;
    }

    /**
     * @param searchContent the searchContent to set
     */
    public void setSearchContent(String searchContent) {
        this.searchContent = searchContent;
    }

    public void createEmployee(ActionEvent actionEvent) {
        selectedEmployee = new Employee();
        selectedEmployee.setXtduser(new Xtduser());

    }

    public void searchByContent(ActionEvent actionEvent) {
        this.employeeList.clear();
        this.employeeList.addAll(employeeFacade.searchByContent(searchContent));
    }

    public void searchByDepartment() {
        this.employeeList.clear();
        this.employeeList.addAll(employeeFacade.searchByDepartment(selectedDepartment));

        postSelectItems.clear();
        List<DepartmentPost> dpList = departmentPostFacade.findByDepartment(selectedDepartment);
        for (DepartmentPost dp : dpList) {
            postSelectItems.add(new SelectItem(dp.getPost(), dp.getPost()));
        }
    }

    public void searchByDepartmentPost() {
        this.employeeList.clear();
        this.employeeList.addAll(employeeFacade.searchByDepartmentPost(selectedDepartment, selectedPost));
    }

    /**
     * @return the selectedDepartment
     */
    public String getSelectedDepartment() {
        return selectedDepartment;
    }

    /**
     * @param selectedDepartment the selectedDepartment to set
     */
    public void setSelectedDepartment(String selectedDepartment) {
        this.selectedDepartment = selectedDepartment;
    }

    /**
     * @return the selectedPost
     */
    public String getSelectedPost() {
        return selectedPost;
    }

    /**
     * @param selectedPost the selectedPost to set
     */
    public void setSelectedPost(String selectedPost) {
        this.selectedPost = selectedPost;
    }

    /**
     * @return the postSelectItems
     */
    public List<SelectItem> getPostSelectItems() {
        if (postSelectItems == null) {
            postSelectItems = new ArrayList();
        }
        return postSelectItems;
    }

    /**
     * @param postSelectItems the postSelectItems to set
     */
    public void setPostSelectItems(List<SelectItem> postSelectItems) {
        this.postSelectItems = postSelectItems;
    }

    /**
     * @return the departmentPostSelectItems
     */
    public List<SelectItem> getDepartmentPostSelectItems() {
        if (departmentPostSelectItems == null) {
            departmentPostSelectItems = new ArrayList();
            List<DepartmentPost> departmentPosts = departmentPostFacade.findAll();
            for (DepartmentPost dp : departmentPosts) {
                departmentPostSelectItems.add(new SelectItem(dp.getId(), dp.toString()));
            }
        }
        return departmentPostSelectItems;
    }

    /**
     * @param departmentPostSelectItems the departmentPostSelectItems to set
     */
    public void setDepartmentPostSelectItems(List<SelectItem> departmentPostSelectItems) {
        this.departmentPostSelectItems = departmentPostSelectItems;
    }

    public void save(ActionEvent actionEvent) {
        RequestContext context = RequestContext.getCurrentInstance();
        boolean isNew = selectedEmployee.isNew();
        this.applicationBean.setEmphasisItems(null);
        this.applicationBean.setEmployeeSelectItemMap(null);
        try {
            employeeFacade.update(selectedEmployee);
            addMessage("保存成功", null);
            context.addCallbackParam("success", true);
            if (isNew) {
                employeeList.add(selectedEmployee);
                applicationBean.setEmployeeSelectItems(null);
            }
        } catch (Exception e) {

            getLogger(this.getClass()).log(Level.FINEST, "商品设置更新失败", e);
            addMessage("保存失败", "请稍候再试", FacesMessage.SEVERITY_ERROR);
            context.addCallbackParam("success", false);
        }
    }

    public void saveAuthority(ActionEvent actionEvent) {


        RequestContext context = RequestContext.getCurrentInstance();

        List<UserGroup> xtdroleList = new ArrayList();
        for (Xtdgroup x : xtdGroups.getTarget()) {
            xtdroleList.add(new UserGroup(selectedEmployee.getXtduser().getUsername(), x.getName()));
        }
        selectedEmployee.getXtduser().setXtdroleList(xtdroleList);

        try {
            employeeFacade.update(selectedEmployee);
            addMessage("保存成功", null);
            context.addCallbackParam("success", true);
        } catch (Exception e) {
            getLogger(this.getClass()).log(Level.FINEST, "商品设置更新失败", e);
            addMessage("保存失败", "请稍候再试", FacesMessage.SEVERITY_ERROR);
            context.addCallbackParam("success", false);
        }
    }

    /**
     * @return the selectedDepartmentPostId
     */
    public int getSelectedDepartmentPostId() {
        if (selectedEmployee != null && selectedEmployee.getDepartmentPost() != null) {
            selectedDepartmentPostId = selectedEmployee.getDepartmentPost().getId();
        }
        return selectedDepartmentPostId;
    }

    /**
     * @param selectedDepartmentPostId the selectedDepartmentPostId to set
     */
    public void setSelectedDepartmentPostId(int selectedDepartmentPostId) {
        this.selectedDepartmentPostId = selectedDepartmentPostId;
        selectedEmployee.setDepartmentPost(departmentPostFacade.find(selectedDepartmentPostId));
    }

    public void checkUniqueEmployeeName(FacesContext context, UIComponent component, Object newValue) {
        if (!employeeFacade.checkUnique(selectedEmployee, "name", (String) newValue, selectedEmployee.isNew())) {
            throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "保存失败", "员工名称有重复"));
        }
    }

    public void checkUniqueUserName(FacesContext context, UIComponent component, Object newValue) {
        if (!xtduserFacade.checkUnique(selectedEmployee.getXtduser(), "username", (String) newValue, selectedEmployee.isNew())) {
            throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "保存失败", "用户名有重复"));
        }
    }

    /**
     * @return the employeeSelectItems
     */
    public List<SelectItem> getEmployeeSelectItems() {
        if (employeeSelectItems == null) {
            employeeSelectItems = new ArrayList();
            List<Employee> employees = employeeFacade.findAll();
            for (Employee e : employees) {
                employeeSelectItems.add(new SelectItem(e.getId(), e.toString()));
            }
        }
        return employeeSelectItems;
    }

    /**
     * @param employeeSelectItems the employeeSelectItems to set
     */
    public void setEmployeeSelectItems(List<SelectItem> employeeSelectItems) {
        this.employeeSelectItems = employeeSelectItems;
    }

    /**
     * @return the selectedEmployeeId
     */
    public int getSelectedEmployeeId() {
        return selectedEmployeeId;
    }

    /**
     * @param selectedEmployeeId the selectedEmployeeId to set
     */
    public void setSelectedEmployeeId(int selectedEmployeeId) {
        this.selectedEmployeeId = selectedEmployeeId;
    }

    public void editAuthorities(ActionEvent actionEvent) {
        selectedEmployee = null;
        xtdGroups = null;
    }

    public void selectEmployee() {
        if (selectedEmployee != null) {
            List<Xtdgroup> target = selectedEmployee.getXtduser().getXtdgroupList();
            List<Xtdgroup> source = xtdgroupFacade.findAll();
            source.removeAll(target);
            xtdGroups = new DualListModel<Xtdgroup>(source, target);
        }
    }

    public void selectAll(ActionEvent actionEvent) {
        selecteEmployeeList = new Employee[employeeList.size()];
        for (int i = 0; i < selecteEmployeeList.length; i++) {
            selecteEmployeeList[i] = employeeList.get(i);
        }
    }

    public void unselectAll(ActionEvent actionEvent) {
        this.selecteEmployeeList = null;
    }

    public void searchAll(ActionEvent actionEvent) {
        this.employeeList.clear();
        this.employeeList.addAll(employeeFacade.findAll());
    }

    /**
     * @return the xtdGroups
     */
    public DualListModel<Xtdgroup> getXtdGroups() {
        if (xtdGroups == null) {
            xtdGroups = new DualListModel<Xtdgroup>();
        }
        return xtdGroups;
    }

    /**
     * @param xtdGroups the xtdGroups to set
     */
    public void setXtdGroups(DualListModel<Xtdgroup> xtdGroups) {
        this.xtdGroups = xtdGroups;
    }

    public void cancellCreate(CloseEvent closeEvent) {
        addMessage("取消保存", null);
    }

    public void calulatePayroll(ActionEvent actionEvent) {
        RequestContext context = RequestContext.getCurrentInstance();
        if (startDate == null || endDate == null) {
            context.addCallbackParam("success", false);
            addMessage("计算失败", "起止时间不可为空", FacesMessage.SEVERITY_WARN);
            return;
        }
        if (startDate.after(endDate)) {
            context.addCallbackParam("success", false);
            addMessage("计算失败", "起止时间输入错误", FacesMessage.SEVERITY_WARN);
            return;
        }
        if (selecteEmployeeList == null || selecteEmployeeList.length == 0) {
            context.addCallbackParam("success", false);
            addMessage("计算失败", "请选定欲派发工资的员工,可多选", FacesMessage.SEVERITY_WARN);
            return;
        }

        this.payrollList.clear();
        try {
            this.payrollList.addAll(payrollFacade.calculatePayroll(selecteEmployeeList, startDate, endDate, sessionBean.getUser()));
        } catch (SystemException ex) {
            Logger.getLogger(EmployeeManager.class.getName()).log(Level.SEVERE, null, ex);
            context.addCallbackParam("success", false);
            addMessage("计算失败", ex.getMessage(), FacesMessage.SEVERITY_WARN);
            return;
        }
        context.addCallbackParam("success", true);
    }

    public void calulateAllPayrolls(ActionEvent actionEvent) {
        RequestContext context = RequestContext.getCurrentInstance();
        if (startDate == null || endDate == null) {
            context.addCallbackParam("success", false);
            addMessage("计算失败", "起止时间不可为空", FacesMessage.SEVERITY_WARN);
            return;
        }
        if (startDate.after(endDate)) {
            context.addCallbackParam("success", false);
            addMessage("计算失败", "起止时间输入错误", FacesMessage.SEVERITY_WARN);
            return;
        }
        if (employeeList == null || employeeList.isEmpty()) {
            context.addCallbackParam("success", false);
            addMessage("计算失败", "请选定欲派发工资的员工,可多选", FacesMessage.SEVERITY_WARN);
            return;
        }
        Employee[] employeeArray = new Employee[employeeList.size()];
        int i = 0;
        for (Employee e : employeeList) {
            employeeArray[i] = e;
            i++;
        }
        this.payrollList.clear();
        try {
            this.payrollList.addAll(payrollFacade.calculatePayroll(employeeArray, startDate, endDate, sessionBean.getUser()));
        } catch (SystemException ex) {
            Logger.getLogger(EmployeeManager.class.getName()).log(Level.SEVERE, null, ex);
            context.addCallbackParam("success", false);
            addMessage("计算失败", ex.getMessage(), FacesMessage.SEVERITY_WARN);
            return;
        }
        context.addCallbackParam("success", true);
    }

    public void confirmPayrolls(ActionEvent actionEvent) {

        payrollFacade.update(payrollList, sessionBean.getUser());
        this.getEmployeeList().clear();
        this.getEmployeeList().addAll(employeeFacade.findAllActive());
        RequestContext context = RequestContext.getCurrentInstance();
        context.addCallbackParam("success", true);
        addMessage("确认成功", null, FacesMessage.SEVERITY_INFO);
    }

    /**
     * @return the applicationBean
     */
    public ApplicationBean getApplicationBean() {
        return applicationBean;
    }

    /**
     * @param applicationBean the applicationBean to set
     */
    public void setApplicationBean(ApplicationBean applicationBean) {
        this.applicationBean = applicationBean;
    }

    /**
     * @return the payrollList
     */
    public List<Payroll> getPayrollList() {
        if (payrollList == null) {
            payrollList = new ArrayList();


        }
        return payrollList;
    }

    /**
     * @param payrollList the payrollList to set
     */
    public void setPayrollList(List<Payroll> payrollList) {
        this.payrollList = payrollList;
    }

    /**
     * @return the selecteEmployeeList
     */
    public Employee[] getSelecteEmployeeList() {

        return selecteEmployeeList;
    }

    /**
     * @param selecteEmployeeList the selecteEmployeeList to set
     */
    public void setSelecteEmployeeList(Employee[] selecteEmployeeList) {
        this.selecteEmployeeList = selecteEmployeeList;
    }

    /**
     * @return the startDate
     */
    public Date getStartDate() {
        return startDate;
    }

    /**
     * @param startDate the startDate to set
     */
    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }

    /**
     * @return the endDate
     */
    public Date getEndDate() {
        return endDate;
    }

    /**
     * @param endDate the endDate to set
     */
    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }

    /**
     * @return the sessionBean
     */
    public SessionBean getSessionBean() {
        return sessionBean;
    }

    /**
     * @param sessionBean the sessionBean to set
     */
    public void setSessionBean(SessionBean sessionBean) {
        this.sessionBean = sessionBean;
    }
}
